<?php
/**
 * FastApp.
 * 9/22/24
 * @Author deepsea159
 * @Contact telegram:deepsea159
 */

namespace App\Fastapp\Api\Service\Callback;

use App\Fastapp\Api\Service\BaseService;
use App\Fastapp\Api\Service\Telegram;
use App\Fastapp\Listener\Event\TgBotJoinGroupEvent;
use App\Fastapp\Model\AccountOtherRelated;
use App\Fastapp\Model\FastappRobotGroup;
use App\Fastapp\Model\FastappRobotGroupAuth;
use App\Fastapp\Model\FastappRobotGroupInvite;
use Hyperf\RateLimit\Annotation\RateLimit;
use Telegram\Bot\Api;

class TelegramCallback extends BaseService
{
    const SOURCE = 1;
    public ?array $botConfig = null;
    public ?Api $bot = null;
    public ?int $bot_id = null;

    public function tgbot(int $robot_id, array $data): bool
    {
        console()->error(json_encode($data, JSON_UNESCAPED_UNICODE));
        $this->botConfig = redis()->hGetAll('bot:' . $robot_id);
        if (!$this->botConfig) return true;
        $this->bot = new Api($this->botConfig['token']);
        $this->bot_id = $robot_id;
        if (isset($data['message'])) {
            $this->message($data['message']);
        } elseif (isset($data['channel_post'])) {
            $this->channelPost($data['channel_post']);
        } elseif (isset($data['my_chat_member'])) {
            $this->myChatMember($data['my_chat_member']);
        } elseif (isset($data['callback_query'])) {
            $this->callbackQuery($data['callback_query'], $data['callback_query']['from']['id']);
        }
        return false;
    }

    //拉机器人
    public function myChatMember(array &$data): void
    {
        if (in_array($data['chat']['type'], ['group', 'supergroup', 'channel']) && in_array($data['new_chat_member']['status'], ['member', 'administrator'])) {
            $tp = [
                'group' => 1,
                'supergroup' => 2,
                'channel' => 3
            ];
            $map = ['group_id' => $data['chat']['id'], 'source' => self::SOURCE];
            $group = FastappRobotGroup::query()->where($map)->first();
            $auth = FastappRobotGroupAuth::query()->where($map)->first();
            if (!$group) $group = new FastappRobotGroup();
            if (!$auth) $auth = new FastappRobotGroupAuth();
            if ($group->user_id) {
                $auth->fill(array_merge($map, ['role' => $data['new_chat_member']['status'], 'bot_id' => $this->bot_id]));
                $auth->save();
                $group->fill(['type' => $tp[$data['chat']['type']], 'name' => $data['chat']['title']])->save();
                api_dispatch(new TgBotJoinGroupEvent($data['from']['id'], $this->bot_id, $data['chat'], true));
                return;
            }
            if (!empty($this->botConfig['account_type'])) {
                $uid = AccountOtherRelated::query()->where([
                    'unique_code' => $data['from']['id'],
                    'related_type' => AccountOtherRelated::TYPE_TELEGRAM,
                    'account_type' => $this->botConfig['account_type']
                ])->value('user_id');
                if ($uid) $map['user_id'] = $uid;
                else $map['user_id'] = Telegram::createUser(array_merge($data['from'], ['type' => $this->botConfig['account_type']]));
            }
            $map['shop_id'] = $this->botConfig['shop_id'] ?? 0;
            $map['source_user'] = $data['from']['id'];
            $map['name'] = $data['chat']['title'];
            $map['type'] = $tp[$data['chat']['type']];
            $group->fill($map);
            $group->save();
            $auth->fill(array_merge($map, ['role' => $data['new_chat_member']['status'], 'bot_id' => $this->bot_id]));
            $auth->save();
            api_dispatch(new TgBotJoinGroupEvent($data['from']['id'], $this->bot_id, $data['chat'], true));
        }
        if (!in_array($data['new_chat_member']['status'], ['member', 'administrator'])) {
            FastappRobotGroupAuth::query()->where(['group_id' => $data['chat']['id'], 'source' => self::SOURCE, 'bot_id' => $this->bot_id])->delete();
            api_dispatch(new TgBotJoinGroupEvent($data['from']['id'], $this->bot_id, $data['chat'], false));
        }
    }

    public function message(array &$data): void
    {
        if (isset($data['new_chat_members'])) {//拉人
            $user_id = $name = [];
            foreach ($data['new_chat_members'] as $member) {
                if ($member['is_bot']) continue;
                $user_id[] = $member['id'];
                $name[$member['id']] = $member['first_name'];
            }

            //发送新人引导
            if (!empty($this->botConfig['config']) && $name) $this->botConfig['config']::guide($data['chat']['id'], $name, $this->bot, $this->bot_id);
            $exitUid = FastappRobotGroupInvite::query()
                ->where(['source' => self::SOURCE])
                ->whereIn('user_id', $user_id)->pluck('user_id')->toArray();
            $in = [];
            foreach (array_diff($user_id, $exitUid) as $uid) {
                $in[] = [
                    'source' => self::SOURCE,
                    'group_id' => $data['chat']['id'],
                    'user_id' => $uid,
                    'parent_id' => $data['from']['id'],
                    'created_at' => date('Y-m-d H:i:s'),
                ];
            }
            if ($in) FastappRobotGroupInvite::query()->insert($in);
            return;
        }

        if (!empty($this->botConfig['config'])) {
            if (method_exists($this->botConfig['config'], 'skipBotMessage') && $data['from']['is_bot']) return;
            $this->botConfig['config']::handle($data, $this->bot, $this->bot_id);
        }
    }

    #[RateLimit(create: 1, capacity: 1, key: 'tg_limit_{from_id}')]
    public function callbackQuery(array &$data, int $from_id): void
    {
        if (!empty($this->botConfig['config'])) $this->botConfig['config']::callbackQuery($data, $this->bot, $this->bot_id);
    }

    public function channelPost(&$data): void
    {
        if (!empty($this->botConfig['config']) && method_exists($this->botConfig['config'], 'channelPost'))
            $this->botConfig['config']::channelPost($data, $this->bot, $this->bot_id);
    }
}